package robocup.component.actions;

/**
 * Abstract super-type for all implemented action. Basically, an action is
 * anything that can be executed by the agents, e.g. a dash or a turn-action, or
 * a speechact.<br>
 * Actions are executed by sending a string-representation with key-words and
 * parameters to the server. Therefore, this class defines the abstract method
 * <code>toString()</code>, which must be overridden by all extending
 * subclasses. These have to create the correct syntax for the actions as
 * defined in the server manual, using the given values as parameter. Note that
 * some actions, which are introduced to the server after the release of the
 * manual, are implemented as well, such as point-to and attention-to.
 * 
 */
public abstract class Action {

  /**
   * IDs for all possible action types. These can be used to check their type
   * without making instanceof tests (for performance reasons).
   */
  public enum TYPE {
    DASH,
    MOVE,
    KICK,
    SAY,
    TURN,
    TURN_NECK,
    CATCH_BALL,
    CHANGE_VIEW_MODE,
    SENSE_BODY,
    TACKLE,
    POINTTO,
    ATTENTIONTO,
    COACH_EYE_MODE,
    COACH_PLAY_MODE,
    COACH_START,
    COACH_MOVE_PLAYER,
    COACH_MOVE_BALL,
    COACH_CHANGE_PLAYER_TYPE,
    COACH_RECOVER,
    COACH_LOOK,
    COACH_EAR_MODE,
    COACH_KILL_PLAYER,
    MAIN;

    /**
     * Checks, if this is a main-action, which is the case, if the action is one
     * of DASH, MOVE, KICK, TURN, CATCH_BALL, SENSE_BODY or TACKLE. Main-actions
     * are actions, which result in a movement and can be executed only
     * exclusive Note that for instance turn-neck is not a main action, because
     * it can be concurrently to main-actions.
     * 
     * @return true if the action is a main action
     */
    public boolean isMain() {

      switch (this) {
        case DASH:
        case MOVE:
        case KICK:
        case TURN:
        case CATCH_BALL:
        case SENSE_BODY:
        case TACKLE:
          return true;
        default:
          return false;
      }
    }
  };

  /**
   * double parameters are rounded to this many decimal places
   */
  static protected final int PARAMETER_PRECISION = 3;

  /**
   * The type of the action.
   */
  protected TYPE             _type;

  /**
   * Default-constructor of the Action-class.
   */
  public Action() {

  }

  /**
   * Getter for the action-type, which corresponds always to the sub-class, i.e
   * the DashAction is always of type TYPE.DASH.
   * 
   * @return the type of this class.
   */
  public TYPE getType() {

    return this._type;
  }

  /**
   * An action is worth sending if it effects the world.
   * 
   * @return true, if the action has an impact on the world. This is for
   *         instance not the case for turn actions with turn-angle 0.
   */
  public boolean isWorthSending() {

    return true;
  }

  /**
   * This definition enforces all extending classes to implement a toString
   * method (which is here set to abstract), such that their string-
   * representation can be sent to the server as command.
   * 
   * @return string - the string-representation of this action in valid syntax.
   */
  @Override
  public abstract String toString();
}
